#include "connection.h"
#include "protocol.h"
#include "messagehandler.h"
#include <string>
#include <iostream>




using namespace std;
using namespace client_server;

/*
 * Reads the int-value encoded in the first 5 bytes of the char* p.
 */
int MessageHandler::readInt(char* &p){
	p++;
	char temp1 = *(p++);
	char temp2 = *(p++);
	char temp3 = *(p++);
	char temp4 = *(p++);
	return (temp1 << 24) | (temp2 << 16) | (temp3 << 8) | temp4;
}

/*
 * Reads the first string encoded in the char* parameters.
 */
string MessageHandler::readString(char* &parameters){
	int i = readInt(parameters);
	string s;
	for(int j = 0; j < i; ++j){
		s += *parameters;
		++parameters;
	}
	return s;
}


/* 
 * Reads and stores the NUM_P value from the connection into the char* p.
 */
int MessageHandler::readNUM_P(char* &p, Connection& conn){
	for(int i = 0; i < 5; ++i)
		*(p++) = conn.read();
	p = p - 5;
	return readInt(p);
}

/*
 * Stores the STRING_P value from the connection into the char* p.
 */
void MessageHandler::readSTRING_P(char* &p, Connection& conn){
	for(int i = 0; i < 5; ++i)
		*(p++) = conn.read();
	p = p - 5;
	int i = readInt(p);
	for(int j = 0; j < i; ++j)
		*(p++) = conn.read();
}

/*
 * Reads a command and parameters from the connection.
 */
MessageHandler::MessageHandler(Connection& conn){
	command = conn.read();
	parameters = new char[342141];
	char* p = parameters;
	if(command == protocol::Protocol::COM_LIST_NG){
		conn.read();	
	} else if (command == protocol::Protocol::COM_CREATE_NG) {
		readSTRING_P(p, conn);
		conn.read();
	} else if (command == protocol::Protocol::COM_DELETE_NG) {
		readNUM_P(p, conn);
		conn.read();
	} else if (command == protocol::Protocol::COM_LIST_ART) {
		readNUM_P(p, conn);
		conn.read();
	} else if (command == protocol::Protocol::COM_CREATE_ART) {
		readNUM_P(p, conn);
		readSTRING_P(p, conn);
		readSTRING_P(p, conn);
		readSTRING_P(p, conn);
		conn.read();
	} else if (command == protocol::Protocol::COM_DELETE_ART) {
		readNUM_P(p, conn);
		readNUM_P(p, conn);
		conn.read();
	} else if (command == protocol::Protocol::COM_GET_ART) {
		readNUM_P(p, conn);
		readNUM_P(p, conn);
		conn.read();
	} else if (command == protocol::Protocol::ANS_LIST_NG) {
		int j = readNUM_P(p, conn);
		for(int i = 0; i < j; ++i){
			readNUM_P(p, conn);
			readSTRING_P(p, conn);
		}
		conn.read();
	} else if (command == protocol::Protocol::ANS_CREATE_NG) {
		if((*(p++) = conn.read()) == protocol::Protocol::ANS_NAK)
			*(p++) = conn.read();
		conn.read();
	} else if (command == protocol::Protocol::ANS_DELETE_NG) {
		if((*(p++) = conn.read()) == protocol::Protocol::ANS_NAK)
			*(p++) = conn.read();
		conn.read();
	} else if (command == protocol::Protocol::ANS_LIST_ART) {
		if((*(p++) = conn.read()) == protocol::Protocol::ANS_ACK){
			int j = readNUM_P(p, conn);
			for(int i = 0; i < j; ++i){
				readNUM_P(p, conn);
				readSTRING_P(p, conn);
			}
		} else
			*(p++) = conn.read();
		conn.read();
	} else if (command == protocol::Protocol::ANS_CREATE_ART) {
		if((*(p++) = conn.read()) == protocol::Protocol::ANS_NAK)
			*(p++) = conn.read();
		conn.read();
	} else if (command == protocol::Protocol::ANS_DELETE_ART) {
		if((*(p++) = conn.read()) == protocol::Protocol::ANS_NAK)
			*(p++) = conn.read();
		conn.read();
	} else if (command == protocol::Protocol::ANS_GET_ART) {
		if((*(p++) = conn.read()) == protocol::Protocol::ANS_ACK){
			readSTRING_P(p, conn);
			readSTRING_P(p, conn);
			readSTRING_P(p, conn);
		} else
			*(p++) = conn.read();
		conn.read();
	}
}
 char MessageHandler::getCommand(){
	return command;
}
char* MessageHandler::getParameters(){
	return parameters;
}
